package com.personal.website.lottery.web.controller;

import com.personal.website.lottery.web.mail.VerifyCodeSender;
import com.personal.website.lottery.web.model.Article;
import com.personal.website.lottery.web.model.User;
import com.personal.website.lottery.web.model.VerifyCode;
import com.personal.website.lottery.web.service.ArticleService;
import com.personal.website.lottery.web.service.UserService;
import com.personal.website.lottery.web.service.VerifyCodeService;
import com.personal.website.lottery.web.util.MD5;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.List;

/**
 * Created by Gavin on 2016/1/24.
 */

@Controller
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private ArticleService articleService;
    @Resource
    private VerifyCodeService verifyCodeService;

    private final Logger logger = LoggerFactory.getLogger(UserController.class);

    @RequestMapping("/registerAction")
    @ResponseBody
    public String registerAction(HttpServletRequest request) {
        String userName = null;
        try {
            userName = URLDecoder.decode(request.getParameter("userName"),"UTF-8");
            String userPassword = URLDecoder.decode(request.getParameter("userPassword"),"UTF-8");
            String sex = URLDecoder.decode(request.getParameter("sex"),"UTF-8");
            String email = URLDecoder.decode(request.getParameter("email"),"UTF-8");
            String mobilePhoneNo = URLDecoder.decode(request.getParameter("mobilePhoneNo"),"UTF-8");
            userPassword = new MD5().getMD5Code(userPassword);
            List<User> dbUserList;
            dbUserList = this.userService.getUserByUserName(userName);
            if(dbUserList.size() != 0){
                return "该用户名已经存在，请使用其他用户名重新注册！";
            }
            dbUserList = this.userService.getUserByEmail(email);
            if(dbUserList.size() != 0){
                return "该邮箱已被注册，请使用其他邮箱注册！";
            }
            dbUserList = this.userService.getUserByMobilePhoneNo(mobilePhoneNo);
            if(dbUserList.size() != 0){
                return "该手机号码已被注册，请使用其他手机号注册！";
            }

            User user = new User();
            user.setUserName(userName);
            user.setEmail(email);
            user.setSex(sex);
            user.setUserPassword(userPassword);
            user.setMobilePhoneNo(mobilePhoneNo);
            user.setIp(request.getRemoteAddr());
            user.setRegisterTime(new Date());
            user.setLastLoginTime(new Date());
            userService.insertUser(user);
        } catch (Exception e) {
            logger.error(String.format("用户'%s'注册失败！", userName), e);
            return "未知异常，注册失败！";
        }
        logger.info(String.format("用户'%s'注册成功！", userName));
        return "恭喜你，注册成功！";
    }

    @RequestMapping("/loginAction")
    @ResponseBody
    public String loginAction(HttpServletRequest request, HttpSession session) {
        String userName = null;
        String userPassword = null;
        List<User> userList = null;
        try {
            userName = URLDecoder.decode(request.getParameter("userName"),"UTF-8");
            userPassword = URLDecoder.decode(request.getParameter("userPassword"),"UTF-8");
            userPassword = new MD5().getMD5Code(userPassword);
            userList = this.userService.getUserByUserName(userName);
            if(userList.size() == 0 || !userList.get(0).getUserPassword().equals(userPassword)){
                return "用户名或密码不对，请重新登陆！";
            } else {
                session.setAttribute("userName",userName);
                session.setAttribute("userId",userList.get(0).getId());
            }
        } catch (Exception e) {
            logger.error(String.format("用户'%s'登录异常！", userName), e);
            return "登录异常！";
        }
        logger.info(String.format("用户'%s'登录成功！", userName));
        return "登录成功！";
    }

    @RequestMapping("/logout")
    public String logout(HttpSession session) {
        String userName = (String) session.getAttribute("userName");
        session.removeAttribute("userName");
        logger.info(String.format("用户'%s'注销成功！", userName));
        return "redirect:/index";
    }

    @RequestMapping("/personalInfo")
    public String personalInfo(HttpSession session,Model model) {
        int userId = -1;
        try {
            userId = (Integer) session.getAttribute("userId");
            model.addAttribute("user",this.userService.getUserById(userId));
        } catch (Exception e) {
            logger.error(String.format("用户'%d'个人信息展示失败！", userId),e);
        }
        return "personalInfo";
    }

    @RequestMapping("/issuedArticles")
    public String issuedArticles(HttpSession session,Model model) {
        int userId = -1;
        try {
            userId = (Integer) session.getAttribute("userId");
            model.addAttribute("articles",this.articleService.getIssuedArticlesByUserId(userId,30));
        } catch (Exception e) {
            logger.error(String.format("用户'%d'展示已发表文章失败！", userId), e);
        }
        return "issuedArticles";
    }

    @RequestMapping("/commentedArticles")
    public String commentedArticles(HttpSession session,Model model) {
        int userId = -1;
        try {
            userId = (Integer) session.getAttribute("userId");
            model.addAttribute("articles", this.articleService.getCommentedArticlesByUserId(userId, 30));
        } catch (Exception e) {
            logger.error(String.format("用户'%d'展示已评论文章失败！", userId), e);
        }
        return "commentedArticles";
    }

    @RequestMapping("/editPassword")
    @ResponseBody
    public String editPassword(HttpSession session,HttpServletRequest request) {
        int userId = -1;
        try {
            String oldPassword = URLDecoder.decode(request.getParameter("oldPassword"), "UTF-8");
            String newPassword = URLDecoder.decode(request.getParameter("newPassword"), "UTF-8");
            MD5 md5 = new MD5();
            oldPassword = md5.getMD5Code(oldPassword);
            newPassword = md5.getMD5Code(newPassword);
            userId = (Integer) session.getAttribute("userId");

            User user = this.userService.getUserById(userId);
            if (!user.getUserPassword().equals(oldPassword)) {
                return "旧密码输入不对，请重新输入！";
            }
            user.setUserPassword(newPassword);
            if(this.userService.updateUser(user)) {
                logger.info(String.format("用户'%d'修改了密码！", userId));
                return "密码修改成功！";
            } else {
                logger.error(String.format("用户'%d'修改密码失败！", userId));
                return "密码修改失败！";
            }
        } catch (Exception e) {
            logger.error(String.format("用户'%d'修改密码失败！", userId), e);
            return "密码修改失败！";
        }

    }

    @RequestMapping("/sendVerifyCode")
    @ResponseBody
    public String sendVerifyCode(HttpServletRequest request) {
        String email = null;
        String userName = null;
        try {
            userName = URLDecoder.decode(request.getParameter("userName"), "UTF-8");
            email = URLDecoder.decode(request.getParameter("email"), "UTF-8");
            if (!this.userService.validateUserInfo(userName, email)) {
                return "用户名和邮箱不匹配！";
            }

            String code = VerifyCodeSender.sendVerifyCode(email);
            VerifyCode verifyCode = new VerifyCode();
            verifyCode.setUserName(userName);
            verifyCode.setEmail(email);
            verifyCode.setVerifyCode(code);
            verifyCode.setCreateTime(new Date());

            this.verifyCodeService.insertVerifyCode(verifyCode);
        } catch (Exception e) {
            logger.error(String.format("用户名'%s',邮箱'%s',发送邮箱验证码失败！", userName, email), e);
            return "验证码发送失败！";
        }
        logger.info(String.format("用户名'%s',邮箱'%s',发送邮箱验证码成功！", userName, email));
        return "发送成功，请查收收件箱或垃圾箱邮件（可能有1-2分钟延迟）。";
    }

    @RequestMapping("/forgetPasswordAction")
    @ResponseBody
    public String forgetPasswordAction(HttpServletRequest request,HttpSession session) {
        String userName = null;
        try {
            userName = URLDecoder.decode(request.getParameter("userName"), "UTF-8");
            String email = URLDecoder.decode(request.getParameter("email"), "UTF-8");
            String verifyCode = URLDecoder.decode(request.getParameter("verifyCode"), "UTF-8");
            Date endDate = new Date();
            endDate.setTime(endDate.getTime() - 3600000);

            if (this.verifyCodeService.validate(userName, email, verifyCode, endDate)) {
                session.setAttribute("forgetPasswordUserName", userName);
                logger.info(String.format("用户'%s'忘记密码时校验验证码成功！", userName));
                return "验证码验证成功！";
            } else {
                logger.error(String.format("用户'%s'忘记密码时校验验证码失败！", userName));
                return "验证码失效或验证失败！";
            }
        } catch (Exception e) {
            logger.error(String.format("用户'%s'忘记密码时校验验证码异常！", userName), e);
            return "验证码验证时异常！";
        }
    }

    @RequestMapping("/editForgetPassword")
    @ResponseBody
    public String editForgetPassword(HttpServletRequest request,HttpSession session) {
        String userName = null;
        try {
            String newPassword = URLDecoder.decode(request.getParameter("newPassword"), "UTF-8");
            userName = (String) session.getAttribute("forgetPasswordUserName");
            newPassword = new MD5().getMD5Code(newPassword);

            User user = this.userService.getUserByUserName(userName).get(0);
            user.setUserPassword(newPassword);
            if(this.userService.updateUser(user)) {
                session.removeAttribute("forgetPasswordUserName");
                logger.info(String.format("用户'%s'修改忘记密码成功！", userName));
                return "修改成功!";
            } else {
                logger.error(String.format("用户'%s'修改忘记密码失败！", userName));
                return "修改失败！";
            }
        } catch (Exception e) {
            logger.error(String.format("用户'%s'修改忘记密码异常！", userName), e);
            return "修改异常！";
        }

    }

}
